package net.chenlin.dp.modules.business.service.impl;

import lombok.extern.slf4j.Slf4j;
import net.chenlin.dp.common.entity.Page;
import net.chenlin.dp.common.entity.Query;
import net.chenlin.dp.common.entity.R;
import net.chenlin.dp.common.exception.RRException;
import net.chenlin.dp.common.utils.CommonUtils;
import net.chenlin.dp.modules.business.dao.DeviceCalibrationMapper;
import net.chenlin.dp.modules.business.entity.dto.deviceCalibration.CalibrationParam;
import net.chenlin.dp.modules.business.entity.dto.deviceCalibration.CheckParam;
import net.chenlin.dp.modules.business.entity.dto.deviceCalibration.CountRatioDto;
import net.chenlin.dp.modules.business.entity.dto.deviceCalibration.DeviceCalibrationDetailDto;
import net.chenlin.dp.modules.business.entity.po.deviceCalibration.DeviceCalibrationCheckPo;
import net.chenlin.dp.modules.business.entity.po.deviceCalibration.DeviceCalibrationDetailPo;
import net.chenlin.dp.modules.business.entity.vo.deviceCalibration.*;
import net.chenlin.dp.modules.business.service.DeviceCalibrationService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author Yangsm
 * @ClassName: DeviceCalibrationServiceImpl
 * @Description: TODO
 * @date 2023年11月23日 16:23
 */
@Slf4j
@Service
public class DeviceCalibrationServiceImpl implements DeviceCalibrationService {

    @Autowired
    private DeviceCalibrationMapper mapper;

    @Override
    public Page<DeviceCalibrationListVo> getDeviceCalibrationList(Map<String, Object> params) {
        Query query = new Query(params);
        Page<DeviceCalibrationListVo> page = new Page<>(query);
        List<DeviceCalibrationListVo> list = mapper.getDeviceCalibrationList(page, query);
        return page;
    }

    @Override
    public void calibration(CalibrationParam param) throws ParseException {

        String calibrationStartTime = param.getCalibrationStartTime();
        Date start = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(calibrationStartTime);
        String calibrationEndTime = param.getCalibrationEndTime();
        Date end = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(calibrationEndTime);

        List<DeviceCalibrationDetailPo> insertList = new ArrayList<>();

        List<DeviceCalibrationCheckPo> checkList = new ArrayList<>();

        param.getIds().stream().forEach(id -> {
            for (int i = 1; i < 4; i++) {
                switch (i) {
                    case 1:
                        DeviceCalibrationDetailPo poA = new DeviceCalibrationDetailPo();
                        poA.setDeviceNo(id);
                        poA.setCalibrationBatch(param.getCalibrationBatch());
                        poA.setCalibrationStartTime(start);
                        poA.setCalibrationEndTime(end);
                        poA.setPhaseSequence("A");
                        insertList.add(poA);

                        DeviceCalibrationCheckPo checkPoA = new DeviceCalibrationCheckPo();

                        checkPoA.setDeviceNo(id);
                        checkPoA.setCalibrationBatch(param.getCalibrationBatch());
                        checkPoA.setPhaseSequence("A");
                        checkList.add(checkPoA);

                        break;
                    case 2:
                        DeviceCalibrationDetailPo poB = new DeviceCalibrationDetailPo();
                        poB.setDeviceNo(id);
                        poB.setCalibrationBatch(param.getCalibrationBatch());
                        poB.setCalibrationStartTime(start);
                        poB.setCalibrationEndTime(end);
                        poB.setPhaseSequence("B");
                        insertList.add(poB);

                        DeviceCalibrationCheckPo checkPoB = new DeviceCalibrationCheckPo();

                        checkPoB.setDeviceNo(id);
                        checkPoB.setCalibrationBatch(param.getCalibrationBatch());
                        checkPoB.setPhaseSequence("B");
                        checkList.add(checkPoB);

                        break;
                    case 3:
                        DeviceCalibrationDetailPo poC = new DeviceCalibrationDetailPo();
                        poC.setDeviceNo(id);
                        poC.setCalibrationBatch(param.getCalibrationBatch());
                        poC.setCalibrationStartTime(start);
                        poC.setCalibrationEndTime(end);
                        poC.setPhaseSequence("C");
                        insertList.add(poC);

                        DeviceCalibrationCheckPo checkPoC = new DeviceCalibrationCheckPo();

                        checkPoC.setDeviceNo(id);
                        checkPoC.setCalibrationBatch(param.getCalibrationBatch());
                        checkPoC.setPhaseSequence("C");
                        checkList.add(checkPoC);

                        break;
                    default:
                        //System.out.println("i是其他值");
                        break;
                }
            }
        });
        mapper.batchInsertDeviceCalibrationDetail(insertList);
        mapper.batchInsertDeviceCalibrationCheck(checkList);
    }

    @Override
    public List<DeviceCalibrationDetailVo> getDeviceCalibrationResult(Map<String, Object> params) {
        List<DeviceCalibrationDetailVo> list = mapper.getDeviceCalibrationResult(params);
        return list;
    }

    @Override
    public void check(CheckParam param) throws ParseException {

        DeviceCalibrationCheckPo po = new DeviceCalibrationCheckPo();
        po.setCalibrationBatch(param.getCalibrationBatch());
        String checkStartTime = param.getCheckStartTime();
        Date start = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(checkStartTime);
        po.setCheckStartTime(start);
        String checkEndTime = param.getCheckEndTime();
        Date end = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(checkEndTime);
        po.setCheckEndTime(end);

        mapper.updateCheckTime(po);

    }

    @Override
    public Page<DeviceCalibrationCheckVo> getDeviceCalibrationCheckResult(Map<String, Object> params) {
        Query query = new Query(params);
        Page<DeviceCalibrationCheckVo> page = new Page<>(query);
        List<DeviceCalibrationCheckVo> list = mapper.getDeviceCalibrationCheckResult(page, query);
        return page;
    }

    @Override
    public R getStep() {

        StepVo vo = new StepVo();

        List<StepVo> stepVoList = mapper.getCalibrationStep();
        if(stepVoList.size() > 1){
            throw new RRException("数据流程有问题，请找后台开发运维人员核对！");
        }

        if(stepVoList.size() == 1){
            vo.setCalibrationBatch(stepVoList.get(0).getCalibrationBatch());
            vo.setStep(3);
            vo.setCalibrationEndTime(stepVoList.get(0).getCalibrationEndTime());
            return CommonUtils.msg(vo);
        }

        List<StepVo> checkStepList = mapper.getCheckStep();

        if(checkStepList.size() > 1){
            throw new RRException("数据流程有问题，请找后台开发运维人员核对！");
        }

        if(checkStepList.size() == 1){
            vo.setCalibrationBatch(checkStepList.get(0).getCalibrationBatch());
            vo.setStep(4);
            return CommonUtils.msg(vo);
        }

        vo.setCalibrationBatch(null);
        vo.setStep(1);

        return CommonUtils.msg(vo);

    }

    @Override
    public R countRatio(CountRatioDto dto) throws ParseException {

        String startTime = dto.getStartTime();
        if(StringUtils.isEmpty(startTime)){
            return R.error("开始时间不能为空");
        }
        String endTime = dto.getEndTime();
        if(StringUtils.isEmpty(endTime)){
            return R.error("结束时间不能为空");
        }
        String deviceNo = dto.getDeviceNo();
        if(StringUtils.isEmpty(deviceNo)){
            return R.error("设备编号不能为空");
        }
        String base = dto.getBase();
        if(StringUtils.isEmpty(base)){
            return R.error("计算基数不能为空");
        }
        BigDecimal baseNum = new BigDecimal(base);

        BigDecimal start = mapper.getStartCountPower(startTime);
        BigDecimal end = mapper.getEndCountPower(endTime);

        BigDecimal result = end.subtract(start);

        CountRatioVo countRatioVo = mapper.getDeviceCoubnt(deviceNo,startTime,endTime);
        if(null == countRatioVo ){
            CountRatioVo vo = new CountRatioVo();
            vo.setCalibrationDifference(result);
            return CommonUtils.msg(vo);
        }

        System.out.println(result);
        countRatioVo.setCalibrationDifference(result);

        BigDecimal multiply = result.multiply(baseNum);

        if (BigDecimal.ZERO.compareTo(countRatioVo.getAPhaseCount()) != 0) {
            BigDecimal aPhaseRatio = multiply.divide(countRatioVo.getAPhaseCount(), 3, RoundingMode.HALF_UP);
            countRatioVo.setAPhaseRatio(aPhaseRatio);
        }else{
            countRatioVo.setAPhaseRatio(new BigDecimal(0.00));
        }

        if (BigDecimal.ZERO.compareTo(countRatioVo.getBPhaseCount()) != 0) {
            BigDecimal bPhaseRatio = multiply.divide(countRatioVo.getBPhaseCount(), 3, RoundingMode.HALF_UP);
            countRatioVo.setBPhaseRatio(bPhaseRatio);
        }else{
            countRatioVo.setBPhaseRatio(new BigDecimal(0.00));
        }

        if (BigDecimal.ZERO.compareTo(countRatioVo.getCPhaseCount()) != 0) {
            BigDecimal cPhaseRatio = multiply.divide(countRatioVo.getCPhaseCount(), 3, RoundingMode.HALF_UP);
            countRatioVo.setCPhaseRatio(cPhaseRatio);
        }else{
            countRatioVo.setCPhaseRatio(new BigDecimal(0.00));
        }

        List<DeviceCalibrationDetailPo> insertList = new ArrayList<>();

        Date calibrationStartTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTime);
        Date calibrationEndTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endTime);

        DeviceCalibrationDetailPo poA = new DeviceCalibrationDetailPo();

        poA.setDeviceNo(deviceNo);
        poA.setCalibrationStartTime(calibrationStartTime);
        poA.setCalibrationEndTime(calibrationEndTime);
        poA.setPhaseSequence("A");
        poA.setDeviceMeteredElectricity(countRatioVo.getAPhaseCount());
        poA.setDeviceMeteredTime(new Date());
        poA.setBaseAmmeteMeteredElectricity(result);
        poA.setBaseAmmeteTime(new Date());
        poA.setCalibrationFactor(countRatioVo.getAPhaseRatio());
        insertList.add(poA);

        DeviceCalibrationDetailPo poB = new DeviceCalibrationDetailPo();

        poB.setDeviceNo(deviceNo);
        poB.setCalibrationStartTime(calibrationStartTime);
        poB.setCalibrationEndTime(calibrationEndTime);
        poB.setPhaseSequence("B");
        poB.setDeviceMeteredElectricity(countRatioVo.getBPhaseCount());
        poB.setDeviceMeteredTime(new Date());
        poB.setBaseAmmeteMeteredElectricity(result);
        poB.setBaseAmmeteTime(new Date());
        poB.setCalibrationFactor(countRatioVo.getBPhaseRatio());
        insertList.add(poB);

        DeviceCalibrationDetailPo poC = new DeviceCalibrationDetailPo();

        poC.setDeviceNo(deviceNo);
        poC.setCalibrationStartTime(calibrationStartTime);
        poC.setCalibrationEndTime(calibrationEndTime);
        poC.setPhaseSequence("C");
        poC.setDeviceMeteredElectricity(countRatioVo.getCPhaseCount());
        poC.setDeviceMeteredTime(new Date());
        poC.setBaseAmmeteMeteredElectricity(result);
        poC.setBaseAmmeteTime(new Date());
        poC.setCalibrationFactor(countRatioVo.getCPhaseRatio());
        insertList.add(poC);

        mapper.deleteDeviceCalibrationDetailByNo(deviceNo);

        mapper.batchInsertDeviceCalibrationDetail(insertList);

        return CommonUtils.msg(countRatioVo);
    }

    @Override
    public Page<DeviceCalibrationDetailVo> getDeviceCalibrationDetailList(Map<String, Object> params) {
        Query query = new Query(params);
        Page<DeviceCalibrationDetailVo> page = new Page<>(query);
        List<DeviceCalibrationDetailVo> list = mapper.getDeviceCalibrationDetailList(page, query);
        return page;
    }

    @Override
    public R updateCalibrationFactor(DeviceCalibrationDetailDto dto) {
        BigDecimal calibrationFactor = mapper.getCalibrationFactor(dto.getDeviceNo(),dto.getPhaseSequence());

        BigDecimal bigDecimal = new BigDecimal(dto.getNum());

        // 乘法
        BigDecimal result = calibrationFactor.multiply(bigDecimal);
        // 保留四位小数，四舍五入
        BigDecimal roundedResult = result.setScale(4, RoundingMode.HALF_UP);

        int i = mapper.updateCalibrationFactor(dto.getDeviceNo(),dto.getPhaseSequence(),roundedResult);

        return CommonUtils.msg(i);
    }
}
